package com.lilingguo.easyserver.dao.impl;

import com.lilingguo.easyserver.dao.ServiceInfoDao;
import com.lilingguo.easyserver.pojo.ServiceInfo;
import lombok.extern.log4j.Log4j2;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.jdbc.core.BeanPropertyRowMapper;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.stereotype.Repository;

import java.util.Collections;
import java.util.List;

/**
 * 持久层实现类
 * 维护服务信息
 *
 * @Author: 黎铃果
 * @Date: 2020/05/28 16:38
 */
@Log4j2
@Repository
public class ServiceInfoDaoImpl implements ServiceInfoDao {

    @Autowired(required = false)
    private JdbcTemplate template;

    @Override
    public void init() {
        try {
            String sql = "CREATE TABLE if not exists `tab_easyserver` (" +
                         "`id` INT PRIMARY KEY AUTO_INCREMENT," +
                         "`name` VARCHAR(64) NOT NULL," +
                         "`ip` VARCHAR(16) NOT NULL," +
                         "`port` INT NOT NULL," +
                         "`registerUrl` VARCHAR(64) NOT NULL," +
                         "`registerTime` DATETIME NOT NULL," +
                         "`ttl` BIGINT NOT NULL," +
                         "`maximalLife` INT NOT NULL," +
                         "`status` INT," +
                         "UNIQUE KEY `UK_idStr` (`name`,`ip`,`port`) );";
            template.execute(sql);
        } catch (Exception e) {
            log.error("failed to init sql table `tab_easyserver`");
        }
    }

    /**
     * 保存服务信息
     */
    @Override
    public int saveInfo(ServiceInfo info) {
        try {
            info.setTtl(System.currentTimeMillis());
            String sql = "insert into `tab_easyserver`(name,ip,port,registerUrl,registerTime,ttl,maximalLife,status) " +
                    "values(?,?,?,?,?,?,?,?)";
            return template.update(sql, info.getName(), info.getIp(), info.getPort(), info.getRegisterUrl(), info.getRegisterTime(), info.getTtl(), info.getMaximalLife(), info.getStatus());
        } catch (Exception e) {
            log.error("failed to save service information -> " + info);
        }
        return -1;
    }

    /**
     * 删除服务信息
     */
    @Override
    public int removeInfo(ServiceInfo info) {
        try {
            String sql = "delete from `tab_easyserver` where name=? and ip=? and port=?";
            return template.update(sql, info.getName(), info.getIp(), info.getPort());
        } catch (Exception e) {
            log.error("failed to remove information [" + info.getIdStr() + "]");
        }
        return -1;
    }

    /**
     * 删除过期服务信息
     */
    @Override
    public void removeExpiredInfos() {
        try {
            long time = System.currentTimeMillis();
            String sql = "delete from `tab_easyserver` where ttl + maximalLife < ?";
            template.update(sql, time);
        } catch (Exception e) {
            log.error("failed to remove information of expired services");
        }
    }

    /**
     * 根据服务名查询服务列表
     */
    @Override
    public List<ServiceInfo> getInfos(String serviceName) {
        try {
            String sql = "select * from `tab_easyserver` where name=?";
            return template.query(sql, new BeanPropertyRowMapper<ServiceInfo>(ServiceInfo.class), serviceName);
        } catch (Exception e) {
            log.error("failed to query information of [" + serviceName + "]");
        }
        return Collections.emptyList();
    }

    /**
     * 根据服务名查询服务
     */
    @Override
    public Integer countInfoByIdStr(ServiceInfo info) {
        try {
            String sql = "select count(*) from `tab_easyserver` where name=? and ip=? and port=?";
            return template.queryForObject(sql, Integer.class, info.getName(), info.getIp(), info.getPort());
        } catch (Exception e) {
            log.error("failed to query quantity of [" + info.getIdStr() + "]");
        }
        return 0;
    }

    /**
     * 续约
     */
    @Override
    public int keepAlive(ServiceInfo info) {
        try {
            info.setTtl(System.currentTimeMillis());
            String sql = "update `tab_easyserver` set ttl=? where name=? and ip=? and port=?";
            return template.update(sql, info.getTtl(), info.getName(), info.getIp(), info.getPort());
        } catch (Exception e) {
            log.error("failed to renew [" + info.getIdStr() + "]");
        }
        return 0;
    }

    /**
     * 返回所有服务列表
     */
    @Override
    public List<ServiceInfo> getAllData() {
        try {
            String sql = "select * from `tab_easyserver`";
            return template.query(sql, new BeanPropertyRowMapper<ServiceInfo>(ServiceInfo.class));
        } catch (Exception e) {
            log.error("failed to query all information of services");
        }
        return Collections.emptyList();
    }

}
